<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
<title>BOSS/WORKER 后台管理</title>
<link rel="icon" href="favicon.ico" type="image/ico">
<meta name="keywords" content="">
<meta name="description" content="">
<meta name="author" content="yinqi">
<link href="/static/css/bootstrap.min.css" rel="stylesheet">
<link href="/static/css/materialdesignicons.min.css" rel="stylesheet">
<link href="/static/css/style.min.css" rel="stylesheet">
</head>

<body>
<div class="lyear-layout-web">
  <div class="lyear-layout-container">
    <!--左侧导航-->
    <aside class="lyear-layout-sidebar">

      <!-- logo -->
      <div id="logo" class="sidebar-header">
        <a href="index.html"><img src="/static/images/logo-sidebar.png" title="LightYear" alt="LightYear" /></a>
      </div>
      <div class="lyear-layout-sidebar-scroll">

        <nav class="sidebar-main">
          <ul class="nav nav-drawer">
            <li class="nav-item active"> <a href="index.html"><i class="mdi mdi-home"></i> 后台首页</a> </li>
            <li class="nav-item nav-item-has-subnav">
              <a href="javascript:void(0)"><i class="mdi mdi-palette"></i>其他操作</a>
              <ul class="nav nav-subnav">
                <li> <a href="lyear_ui_tables.html">表格</a> </li>
              </ul>
            </li>
          </ul>
        </nav>

        <div class="sidebar-footer">
          <p class="copyright">Copyright &copy; 2020. <a target="_blank" href="https://github.com/mengdj">mengdj</a> All rights reserved.</p>
        </div>
      </div>

    </aside>
    <!--End 左侧导航-->

    <!--头部信息-->
    <header class="lyear-layout-header">

      <nav class="navbar navbar-default">
        <div class="topbar">

          <div class="topbar-left">
            <div class="lyear-aside-toggler">
              <span class="lyear-toggler-bar"></span>
              <span class="lyear-toggler-bar"></span>
              <span class="lyear-toggler-bar"></span>
            </div>
            <span class="navbar-page-title"> 管理后台 </span>
          </div>

          <ul class="topbar-right">
            <li class="dropdown dropdown-profile">
              <a href="javascript:void(0)" data-toggle="dropdown">
                <img class="img-avatar img-avatar-48 m-r-10" src="/static/images/users/avatar.jpeg" alt="笔下光年" />
                <span>admin<span class="caret"></span></span>
              </a>
              <ul class="dropdown-menu dropdown-menu-right">
                <li> <a href="/"><i class="mdi mdi-logout-variant"></i> 退出登录</a> </li>
              </ul>
            </li>
            <!--切换主题配色-->
		    <li class="dropdown dropdown-skin">
			  <span data-toggle="dropdown" class="icon-palette"><i class="mdi mdi-palette"></i></span>
			  <ul class="dropdown-menu dropdown-menu-right" data-stopPropagation="true">
                <li class="drop-title"><p>主题</p></li>
                <li class="drop-skin-li clearfix">
                  <span class="inverse">
                    <input type="radio" name="site_theme" value="default" id="site_theme_1" checked>
                    <label for="site_theme_1"></label>
                  </span>
                  <span>
                    <input type="radio" name="site_theme" value="dark" id="site_theme_2">
                    <label for="site_theme_2"></label>
                  </span>
                  <span>
                    <input type="radio" name="site_theme" value="translucent" id="site_theme_3">
                    <label for="site_theme_3"></label>
                  </span>
                </li>
			    <li class="drop-title"><p>LOGO</p></li>
				<li class="drop-skin-li clearfix">
                  <span class="inverse">
                    <input type="radio" name="logo_bg" value="default" id="logo_bg_1" checked>
                    <label for="logo_bg_1"></label>
                  </span>
                  <span>
                    <input type="radio" name="logo_bg" value="color_2" id="logo_bg_2">
                    <label for="logo_bg_2"></label>
                  </span>
                  <span>
                    <input type="radio" name="logo_bg" value="color_3" id="logo_bg_3">
                    <label for="logo_bg_3"></label>
                  </span>
                  <span>
                    <input type="radio" name="logo_bg" value="color_4" id="logo_bg_4">
                    <label for="logo_bg_4"></label>
                  </span>
                  <span>
                    <input type="radio" name="logo_bg" value="color_5" id="logo_bg_5">
                    <label for="logo_bg_5"></label>
                  </span>
                  <span>
                    <input type="radio" name="logo_bg" value="color_6" id="logo_bg_6">
                    <label for="logo_bg_6"></label>
                  </span>
                  <span>
                    <input type="radio" name="logo_bg" value="color_7" id="logo_bg_7">
                    <label for="logo_bg_7"></label>
                  </span>
                  <span>
                    <input type="radio" name="logo_bg" value="color_8" id="logo_bg_8">
                    <label for="logo_bg_8"></label>
                  </span>
				</li>
				<li class="drop-title"><p>头部</p></li>
				<li class="drop-skin-li clearfix">
                  <span class="inverse">
                    <input type="radio" name="header_bg" value="default" id="header_bg_1" checked>
                    <label for="header_bg_1"></label>
                  </span>
                  <span>
                    <input type="radio" name="header_bg" value="color_2" id="header_bg_2">
                    <label for="header_bg_2"></label>
                  </span>
                  <span>
                    <input type="radio" name="header_bg" value="color_3" id="header_bg_3">
                    <label for="header_bg_3"></label>
                  </span>
                  <span>
                    <input type="radio" name="header_bg" value="color_4" id="header_bg_4">
                    <label for="header_bg_4"></label>
                  </span>
                  <span>
                    <input type="radio" name="header_bg" value="color_5" id="header_bg_5">
                    <label for="header_bg_5"></label>
                  </span>
                  <span>
                    <input type="radio" name="header_bg" value="color_6" id="header_bg_6">
                    <label for="header_bg_6"></label>
                  </span>
                  <span>
                    <input type="radio" name="header_bg" value="color_7" id="header_bg_7">
                    <label for="header_bg_7"></label>
                  </span>
                  <span>
                    <input type="radio" name="header_bg" value="color_8" id="header_bg_8">
                    <label for="header_bg_8"></label>
                  </span>
				</li>
				<li class="drop-title"><p>侧边栏</p></li>
				<li class="drop-skin-li clearfix">
                  <span class="inverse">
                    <input type="radio" name="sidebar_bg" value="default" id="sidebar_bg_1" checked>
                    <label for="sidebar_bg_1"></label>
                  </span>
                  <span>
                    <input type="radio" name="sidebar_bg" value="color_2" id="sidebar_bg_2">
                    <label for="sidebar_bg_2"></label>
                  </span>
                  <span>
                    <input type="radio" name="sidebar_bg" value="color_3" id="sidebar_bg_3">
                    <label for="sidebar_bg_3"></label>
                  </span>
                  <span>
                    <input type="radio" name="sidebar_bg" value="color_4" id="sidebar_bg_4">
                    <label for="sidebar_bg_4"></label>
                  </span>
                  <span>
                    <input type="radio" name="sidebar_bg" value="color_5" id="sidebar_bg_5">
                    <label for="sidebar_bg_5"></label>
                  </span>
                  <span>
                    <input type="radio" name="sidebar_bg" value="color_6" id="sidebar_bg_6">
                    <label for="sidebar_bg_6"></label>
                  </span>
                  <span>
                    <input type="radio" name="sidebar_bg" value="color_7" id="sidebar_bg_7">
                    <label for="sidebar_bg_7"></label>
                  </span>
                  <span>
                    <input type="radio" name="sidebar_bg" value="color_8" id="sidebar_bg_8">
                    <label for="sidebar_bg_8"></label>
                  </span>
				</li>
			  </ul>
			</li>
            <!--切换主题配色-->
          </ul>

        </div>
      </nav>

    </header>
    <!--End 头部信息-->

    <!--页面主要内容-->
    <main class="lyear-layout-content">
      <div class="container-fluid">
        <div class="row">
          <div class="col-sm-6 col-lg-3">
            <div class="card bg-danger">
              <div class="card-body clearfix">
                <div class="pull-right">
                  <p class="h6 text-white m-t-0">用户</p>
                  <p class="h3 text-white m-b-0 fa-1-5x" id="total_worker_num">0</p>
                </div>
                <div class="pull-left"> <span class="img-avatar img-avatar-48 bg-translucent"><i class="mdi mdi-account fa-1-5x"></i></span> </div>
              </div>
            </div>
          </div>

          <div class="col-sm-6 col-lg-3">
            <div class="card bg-purple">
              <div class="card-body clearfix">
                <div class="pull-right">
                  <p class="h6 text-white m-t-0">QPS</p>
                  <p class="h3 text-white m-b-0 fa-1-5x" id="qps_num_for_second">0</p>
                </div>
                <div class="pull-left"> <span class="img-avatar img-avatar-48 bg-translucent"><i class="mdi mdi-comment-outline fa-1-5x"></i></span> </div>
              </div>
            </div>
          </div>
        </div>
        <div class="row">
          <div class="col-lg-12">
            <div class="card">
              <div class="card-header">
                <h4>客户信息(<span id="online_worker_num">0</span>)</h4>
                <div class="btn-group btn-group-sm" style="float:right" role="group" aria-label="...">
                  <button type="button" class="btn btn-default" onclick="javascript:void(refresh());">刷 新(<span class="selected_count">0</span>)</button>
                </div>
              </div>
              <div class="card-body">
                <div class="row work-list">
                  <!--
                  <div class="col-xs-6 col-md-3 work-item">
                    <a href="#" class="thumbnail">
                      <img src="" alt="">
                    </a>
                  </div>
                  -->
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </main>
    <!--End 页面主要内容-->
  </div>
</div>

<script type="text/javascript" src="/static/js/jquery.min.js"></script>
<script type="text/javascript" src="/static/js/bootstrap.min.js"></script>
<script type="text/javascript" src="/static/js/perfect-scrollbar.min.js"></script>
<script type="text/javascript" src="/static/js/main.min.js"></script>
<script type="text/javascript" src="/static/js/bootstrap-notify.min.js"></script>

<style type="text/css">
  a.thumbnail{border:1px solid #eee;}
  div.work-list>div[select="1"]>a{background:#2b542c;}
</style>

<script type="text/javascript">
var intval={ping:{id:0},pong:{id:0,reply:0,count:0}};
var selected_elements=[];
var ws;

function stamp(){
  return parseInt(+new Date()/1000);
}
function filterLine(s){
  return s.replace(/\./g,'_');
}

/** 刷新所选客户获取最新的信息 */
function refresh(){
  if(!selected_elements.length){
    alert("尚未选择任何客户");
    return;
  }
  //发送指令获取最新的信息
  if(ws){
    ws.send("REFRESH_SELECTED_WORKER:"+selected_elements.join(";"));
  }
}

/** 同步元素 */
function syncSelectedElements(){
  var count=0;
  selected_elements=[];
  $("div.work-list>div[select='1']").each(function (i,e){
    selected_elements.push($(e).attr("val"));
    count++;
  });
  $("span.selected_count").text(count);
}

function wsocket(server){
  //处理websocket
  ws = new WebSocket(server);
  ws.onopen = function(evt) {
    ws.send("QUERY_WORKERS");
    if(0==intval.ping.id){
      intval.ping.id=setInterval(function(){
        if(ws){
          ws.send("PING")
        }
      },1000);
      intval.pong.id=setInterval(function(){
        //检查服务器是否掉线，是否需要重连(心跳包含其他数据包)
        if(stamp()-intval.pong.reply>=10){
          //可能掉线了
          intval.pong.count++;
          clearInterval(intval.ping.id);
          clearInterval(intval.pong.id);
          if(intval.pong.count<5){
            //尝试重连,最多连接5次，5次失败后不再尝试
            wsocket(server);
          }else{
            clearInterval(intval.ping.id);
            clearInterval(intval.pong.id);
          }
        }
      },1000);
    }
  };
  ws.onmessage = function(evt) {
    eval("var data="+evt.data+";");
    var total_worker_num=$("#total_worker_num");
    var online_worker_num=$("#online_worker_num");
    if("QUERY_WORKERS"==data.query){
      //处理返回所有在线客户效果
      count=0;
      $.each(data.response,function(i,e){
        $("div.work-list").append('<div class="col-xs-6 col-md-3 work-item" status="1" select="0" val="'+e.address+'" id="worker-'+filterLine(e.address)+'"><a href="javascript:void(0)" class="thumbnail"><img src="'+e.thumb+'" alt=""></a></div>');
        count++;
      });
      total_worker_num.text(count);
    }else if("WORKER_ONLINE"==data.query){
      //客户上线
      var ele=$("div.work-list").find("div#worker-"+filterLine(data.response.address))
      if(ele.length){
        ele.find('a').css('border','1px solid #eee');
        ele.attr("status",1);
      }else{
        $("div.work-list").append('<div class="col-xs-6 col-md-3 work-item" select="0" status="1" val="'+data.response.address+'" id="worker-'+filterLine(data.response.address)+'"><a href="javascript:void(0)" class="thumbnail"><img src="'+data.response.thumb+'" alt=""></a></div>');
      }
      online_worker_num.text(parseInt(online_worker_num.text())+1);
      $.notify({icon: 'glyphicon glyphicon-star',title:"上线提醒",message:"客户"+data.response.address+"上线了"});
    }else if("WORKER_OFFLINE"==data.query){
      //客户下线
      var ele=$("div.work-list").find("div#worker-"+filterLine(data.response.address)+">a");
      if(ele.length){
       ele.css('border','1px solid red');
       ele.attr("status",0);
      }
      online_worker_num.text(parseInt(online_worker_num.text())-1);
      $.notify({icon: 'glyphicon glyphicon-star',title:"下线提醒",message:"客户"+data.response.address+"下线了"});
    }else if("WORKER_QPS"==data.query){
      //更新QPS信息
      $("#qps_num_for_second").text(data.response.count);
    }else if("WORKER_UPDATE"==data.query){
      //单个数据更新时
      var ele=$("div.work-list").find("div#worker-"+filterLine(data.response.address)+">a");
      if(ele.length){
        ele.find("img").attr("src",data.response.thumb);
      }
    }
    intval.pong.reply=stamp;
  };
  ws.onclose = function(evt) {
    if(0!=intval.ping.id){
      clearInterval(intval.ping.id);
    }
    if(0!=intval.pong.id){
      clearInterval(intval.pong.id);
    }
    ws=0;
  };
}
$(function(){
  wsocket("ws://{{.server}}{{.port}}/ping?token={{.token}}");
  $("div.work-list").on("click","div",function(){
    if($(this).attr("status")=="1"){
      //切换选择
      if($(this).attr("select")=="0"){
        $(this).attr("select","1");
      }else{
        $(this).attr("select","0");
      }
    }
    syncSelectedElements();
  });
});
</script>
</body>
</html>
